package com.lzw.DailyAudit.service.dateAggregation_02;


import com.baomidou.dynamic.datasource.annotation.DS;
import com.hooya.fa.eu.biz.DailyAudit.entity.DailyAuditStatus;
import com.hooya.fa.eu.biz.DailyAudit.entity.StkOrigDataCollect;
import com.hooya.fa.eu.biz.DailyAudit.entity.dto.ThDataDTO;
import com.hooya.fa.eu.biz.DailyAudit.mapper.DailyAuditStatusMapper;
import com.hooya.fa.eu.biz.DailyAudit.mapper.DailyMetaStkCustomsMapper;
import com.hooya.fa.eu.biz.DailyAudit.mapper.DailyTempThjlMapper;
import com.xxl.job.core.context.XxlJobHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@DS("fa_eu_daily")
public class Insert_TH {

    @Autowired
    private DailyTempThjlMapper dailyTempThjlMapper;

    @Autowired
    private DailyMetaStkCustomsMapper dailyMetaStkCustomsMapper;

    @Autowired
    private CommonService commonService;

	@Autowired
	private DailyAuditStatusMapper statusMapper;

	public void insert_th(String currentDate) {
		try {

			String name = "insertTh-02";
			DailyAuditStatus dailyAuditStatus = statusMapper.selectStatus(name, currentDate);
			if(dailyAuditStatus != null && dailyAuditStatus.getFlag() == 1){
				log.info("{} - 该方法已执行，进行跳过！",name);
				return;
			}
			log.info("开始执行Insert_TH");

            // 获取主数据
            List<ThDataDTO> mainData = dailyTempThjlMapper.getThMainData(currentDate); // fa_eu.temp_thjl a,fa_eu.meta_warehouse b

            // 处理索引
            for (int i = 0; i < mainData.size(); i++) {
                mainData.get(i).setIndex(i + "");
            }

            //获取操作数据
            List<ThDataDTO> cutMainData = new ArrayList<>();
            mainData.forEach(data -> {
                ThDataDTO newItem = new ThDataDTO();
                newItem.setSku(data.getCpbh());
                newItem.setInoutDate(data.getDate());
                newItem.setBelongs(data.getBelongs());
                newItem.setAbbrbelongs(data.getAbbrbelongs());
                newItem.setIndex(data.getIndex());
                cutMainData.add(newItem);
            });

            // 添加价格信息
            Map<String, List<ThDataDTO>> priceDataMap = addPrice(cutMainData, currentDate);
            List<ThDataDTO> withPriceData = priceDataMap.get("withPrice");
            List<ThDataDTO> withoutPriceData = priceDataMap.get("withoutPrice");

            // 添加异常价格信息
            List<ThDataDTO> abnormalPriceData = addAbnormalPrice(withoutPriceData, currentDate);

            List<ThDataDTO> allPriceData = new ArrayList<>(withPriceData);
            allPriceData.addAll(abnormalPriceData);


            //构建海运数据的Map映射集合
            Map<String, List<ThDataDTO>> allPriceDataMap = allPriceData.stream().collect(Collectors.groupingBy(f -> f.getSku() + "|" + f.getIndex()));
            List<ThDataDTO> finalData = new ArrayList<>();
            for (ThDataDTO mainItem : mainData) {
                String key = mainItem.getCpbh() + "|" + mainItem.getIndex();
                if (allPriceDataMap.containsKey(key)) {
                    List<ThDataDTO> ThDataDTOS = allPriceDataMap.get(key);
                    ThDataDTOS.forEach(f -> {
                        ThDataDTO newItem = new ThDataDTO();
                        BeanUtils.copyProperties(mainItem, newItem);
                        newItem.setInoutDate(f.getInoutDate());
                        newItem.setInvoicedate(f.getInvoicedate());
                        newItem.setCurrency(f.getCurrency());
                        newItem.setPrice(f.getPrice());
                        finalData.add(newItem);
                    });
                } else {
                    finalData.add(mainItem);
                }
            }
            
            // 数据验证
            commonService.dataVerificationTh(finalData);

            // 转换为StkOrigdataCollect对象并批量插入
            List<StkOrigDataCollect> records = commonService.convertThToStkOrigDataCollect(finalData);
            commonService.batchInsert(records); // fa_eu_daily.stk_origData_collect

			// 修改执行状态
			commonService.UpdateOrInsertStatus(dailyAuditStatus, name, currentDate);

			log.info("退货数据插入任务完成");
			XxlJobHelper.log("退货数据插入任务完成");
        } catch (Exception e) {
            log.error("退货数据插入任务失败", e);
			XxlJobHelper.log("退货数据插入任务失败");
            throw new RuntimeException("退货数据插入任务失败", e);
        }
    }

    /**
     * 添加价格
     */
    private Map<String, List<ThDataDTO>> addPrice(List<ThDataDTO> cutMainData, String priceDate) {
        try {
            log.info("开始添加价格数据，价格日期: {}", priceDate);
            Map<String, List<ThDataDTO>> result = new HashMap<>();

            List<ThDataDTO> PriceData = dailyMetaStkCustomsMapper.getThPriceData().stream().filter(f -> f.getPrice() != null).collect(Collectors.toList()); //fa_eu.meta_stk_customs

            Map<String, List<ThDataDTO>> PriceDataMap = PriceData.stream().collect(Collectors.groupingBy(f -> f.getSku() + "|" + f.getPricebelongs()));
            List<ThDataDTO> mergeData = new ArrayList<>();
            for (ThDataDTO mainItem : cutMainData) {
                String key = mainItem.getSku() + "|" + mainItem.getAbbrbelongs();
                if (PriceDataMap.containsKey(key)) {
                    List<ThDataDTO> ThDataDTOS = PriceDataMap.get(key);
                    ThDataDTOS.forEach(f -> {
                        ThDataDTO newItem = new ThDataDTO();
                        BeanUtils.copyProperties(mainItem, newItem);
                        newItem.setInvoicedate(f.getInvoicedate());
                        newItem.setCurrency(f.getCurrency());
                        newItem.setQty(f.getQty());
                        newItem.setPrice(f.getPrice());
                        newItem.setPricebelongs(f.getPricebelongs());
                        mergeData.add(newItem);
                    });
                } else {
                    mergeData.add(mainItem);
                }
            }

            List<ThDataDTO> withPriceData = mergeData.stream().filter(f -> f.getPrice() != null).collect(Collectors.toList());

            if (priceDate.equals("inoutdate")) {
                withPriceData.forEach(f -> f.setDateDiffer(ChronoUnit.DAYS.between(LocalDate.parse(f.getInvoicedate(), DateTimeFormatter.ofPattern("yyyy-MM-dd")), LocalDate.parse(f.getInoutDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd")))));
            } else {
                withPriceData.forEach(f -> f.setDateDiffer(ChronoUnit.DAYS.between(LocalDate.parse(f.getInvoicedate(), DateTimeFormatter.ofPattern("yyyy-MM-dd")), LocalDate.parse(priceDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")))));
            }

            //完成了 日期的天数差值计算
            withPriceData = calculateDateAndGetFirstData(withPriceData);

            List<String> withPriceDataIndexList = withPriceData.stream().map(ThDataDTO::getIndex).collect(Collectors.toList());

            List<ThDataDTO> withoutPriceData = cutMainData.stream().filter(f -> !withPriceDataIndexList.contains(f.getIndex())).collect(Collectors.toList());

            result.put("withPrice", withPriceData);
            result.put("withoutPrice", withoutPriceData);
            log.info("添加价格数据完成，有价格数据: {} 条，无价格数据: {} 条", withPriceData.size(), withoutPriceData.size());
            return result;
        } catch (Exception e) {
            log.error("添加价格数据失败", e);
            throw new RuntimeException("添加价格数据失败", e);
        }
    }

    /**
     * 计算日期差值并根据条件排序分组取得第一条记录
     */
    private static List<ThDataDTO> calculateDateAndGetFirstData(List<ThDataDTO> withPriceData) {
        withPriceData = withPriceData.stream().filter(f -> f.getDateDiffer() > 0).collect(Collectors.toList());

        // 按照日期差、数量、出口价格排序，然后按cpbh和index(sheetNumber+direction)分组，取每组第一条记录
        Map<String, List<ThDataDTO>> groupedData = withPriceData.stream().sorted(Comparator.comparing(ThDataDTO::getDateDiffer, Comparator.nullsLast(Comparator.naturalOrder())).thenComparing(ThDataDTO::getQty, Comparator.nullsLast(Comparator.reverseOrder())).thenComparing(ThDataDTO::getPrice, Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.groupingBy(f -> f.getSku() + f.getInoutDate() + f.getIndex()));

        // 取每组第一条记录
        Map<String, ThDataDTO> withPriceDataMap = new HashMap<>();
        for (String key : groupedData.keySet()) {
            List<ThDataDTO> group = groupedData.get(key);
            if (!withPriceDataMap.containsKey(key) && !group.isEmpty()) {
                withPriceDataMap.put(key, group.get(0));
            }
        }

        withPriceData = new ArrayList<>(withPriceDataMap.values());
        return withPriceData;
    }

    /**
     * 添加异常价格
     */
    private List<ThDataDTO> addAbnormalPrice(List<ThDataDTO> withoutPriceData, String priceDate) {
        try {
            log.info("开始添加异常价格数据，价格日期: {}", priceDate);

            List<ThDataDTO> PriceData = dailyMetaStkCustomsMapper.getThPriceData().stream().filter(f -> f.getPrice() != null).collect(Collectors.toList()); //fa_eu.meta_stk_customs

            Map<String, List<ThDataDTO>> PriceDataMap = PriceData.stream().collect(Collectors.groupingBy(ThDataDTO::getSku));

            //merge -->  mainData数据和plnPriceData数据
            List<ThDataDTO> mergeData = new ArrayList<>();
            for (ThDataDTO mainItem : withoutPriceData) {
                String key = mainItem.getSku();
                if (PriceDataMap.containsKey(key)) {
                    List<ThDataDTO> ThDataDTOS = PriceDataMap.get(key);
                    ThDataDTOS.forEach(f -> {
                        ThDataDTO newItem = new ThDataDTO();
                        BeanUtils.copyProperties(mainItem, newItem);
                        newItem.setInvoicedate(f.getInvoicedate());
                        newItem.setCurrency(f.getCurrency());
                        newItem.setQty(f.getQty());
                        newItem.setPrice(f.getPrice());
                        newItem.setPricebelongs(f.getPricebelongs());
                        mergeData.add(newItem);
                    });
                } else {
                    mergeData.add(mainItem);
                }
            }

            //去除价格为空的记录
            List<ThDataDTO> abWithPriceData = mergeData.stream().filter(f -> f.getPrice() != null).collect(Collectors.toList());

            //计算differDate值
            if (priceDate.equals("inoutdate")) {
                abWithPriceData.forEach(f -> f.setDateDiffer(ChronoUnit.DAYS.between(LocalDate.parse(f.getInvoicedate(), DateTimeFormatter.ofPattern("yyyy-MM-dd")), LocalDate.parse(f.getInoutDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd")))));
            } else {
                abWithPriceData.forEach(f -> f.setDateDiffer(ChronoUnit.DAYS.between(LocalDate.parse(f.getInvoicedate(), DateTimeFormatter.ofPattern("yyyy-MM-dd")), LocalDate.parse(priceDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")))));
            }

            //完成了 日期的天数差值计算
            abWithPriceData = calculateDateAndGetFirstData(abWithPriceData);

            log.info("添加异常价格数据完成，处理数据: {} 条", abWithPriceData.size());
            return abWithPriceData;
        } catch (Exception e) {
            log.error("添加异常价格数据失败", e);
            throw new RuntimeException("添加异常价格数据失败", e);
        }
    }


}
